package com.gitee.wsl.struct.either

import arrow.core.Either
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*

/*
class EitherSerializer<T1, T2>(
    t1Serializer: KSerializer<T1>,
    t2Serializer: KSerializer<T2>,
) : KSerializer<Either<T1, T2>> {
    @OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
    override val descriptor: SerialDescriptor = buildSerialDescriptor(
        "TypedSerializer",
        SerialKind.CONTEXTUAL
    ) {
        element("type", String.serializer().descriptor)
        element("value", ContextualSerializer(Either::class).descriptor)
    }
    private val t1EitherSerializer = Either.Left.serializer(t1Serializer)
    private val t2EitherSerializer = Either.Right.serializer(t2Serializer)

    override fun deserialize(decoder: Decoder): Either<T1, T2> {
        return decoder.decodeStructure(descriptor) {
            var type: String? = null
            lateinit var result: Either<T1, T2>
            while (true) {
                when (val index = decodeElementIndex(descriptor)) {
                    0 -> type = decodeStringElement(descriptor, 0)
                    1 -> {
                        result = when (type) {
                            "t1" -> decodeSerializableElement(
                                descriptor,
                                1,
                                t1EitherSerializer
                            )
                            "t2" -> decodeSerializableElement(
                                descriptor,
                                1,
                                t2EitherSerializer
                            )
                            else -> error("Unknown type of either: $type")
                        }
                    }
                    CompositeDecoder.DECODE_DONE -> break
                    else -> error("Unexpected index: $index")
                }
            }
            result
        }
    }


    override fun serialize(encoder: Encoder, value: Either<T1, T2>) {
        encoder.encodeStructure(descriptor) {
            when (value) {
                is Either.Left -> {
                    encodeStringElement(descriptor, 0, "t1")
                    encodeSerializableElement(descriptor, 1, t1EitherSerializer, value)
                }
                is Either.Right -> {
                    encodeStringElement(descriptor, 0, "t2")
                    encodeSerializableElement(descriptor, 1, t2EitherSerializer, value)
                }
            }
        }
    }
}*/


